/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package button_tools;
import button_tools.TPaintSettings.TOOLS;
import java.awt.*;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import javax.swing.*;
import javax.swing.border.Border;
import java.awt.Color;
import java.awt.geom.Point2D;


public class TDraw_Panel extends JPanel implements MouseListener,
        MouseMotionListener
{
    /**
     * Data Types
     */
    private int mouse_x = 0;
    private int mouse_y = 0;
    private int counter = 0;
    private Point2D[] point = new Point2D[3];
    private int height = 0;
    private int width = 0;
  
    private TPaintSettings m_Settings;


    private boolean fill = false;
    private boolean nonfill = true;

    /**
     * Constructor
     */
    public TDraw_Panel(TPaintSettings settings)
    {
        // call init to initialize this panel
       init();
       // add a mouselistener to this
       addMouseListener(this);
       // add a mouse motion listener
       addMouseMotionListener(this);

       
       m_Settings = settings;
    }

    public void addShape(TShape s)
    {
        m_Settings.m_DrawBuffer.add(s);
    }
    public void init()
    {
        // initialize
        Border panelBorder = BorderFactory.createLoweredBevelBorder();
        setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
        setBackground(Color.WHITE);
        setLocation(100,0);
        setSize(700,600);
        setBorder(panelBorder);
    }

    // this functions sets the mouse_x and mouse_y coordinates
    public void mousePressed(MouseEvent e)
    {
            // update x as pressed x
            mouse_x = e.getX();
            // update y as pressed y
            mouse_y = e.getY();  

        if (m_Settings.getTool() == TOOLS.SELECTOR)
        {
            // call update function to relocate object that is selected
             selectShape();  
        } 
        if (m_Settings.getTool() == TOOLS.TRIANGLE)
        {
            
            if (counter > 2)
            {
                counter = 0;
            }         
            
               this.point[counter] = e.getPoint();
               counter++;
        }
              
    }
    /**
     * The mouseReleased funtion is responsible for creating the new objects which
     * is dependent on if a particular shape is slected.
     * @param e
     */
    public void mouseReleased(MouseEvent e)
    {
        TOOLS currentTool = m_Settings.getTool();
        Color color = m_Settings.getColor();
        boolean filled = m_Settings.getFilled();

        switch (currentTool) {
            // creates a new line object based on the x and y coords that were pressed and the x and y which are the width and height
            case LINE: TLine l = new TLine(color, mouse_x, mouse_y, width,height);
                       addShape(l); // add shape
                       break;
            // creates a new circle object based on the x and y coords that were pressed and the x and y which are the width and height
            case CIRCLE: TCircle c = new TCircle(color, mouse_x, mouse_y, width, height);
                        c.setFilled(filled); // set filled if true
                        addShape(c); // add shape
                        break;
            // creates a new rectangle object based on the x and y coords that were pressed and the x and y which are the width and height
            case RECTANGLE: TRectangle rec = new TRectangle(color, mouse_x, mouse_y, width, height);
                            rec.setFilled(filled); // set filled if true
                            addShape(rec); // add shape
                            break;
            // creates a new line object based on the x and y coords that were pressed and the x and y which are the width and height
            case BRUSH: TBrush b = new TBrush(color, mouse_x, mouse_y, m_Settings.getSize(), m_Settings.getSize());
                        addShape(b);
                        break;
                        // if counter is = to three then create a new triangle object
            case TRIANGLE:
                        if (counter == 3)
                        {
                            TTriangle t = new TTriangle(color, point[0], point[1],point[2]);
                            addShape(t);
                        }
                        
                        break;
            case SELECTOR:
                // the selector tool is responsible for checking to see
                // if it is within the bounds of the bottom object
                
                        // loop through each instance of shape in the drawing buffer
                        for (TShape selected : m_Settings.m_SelectedBuffer)
                        {
                          
                            // update the shape has its moved accross the screen...
                            // the new coordinates are the distance between the shapes new coordinates
                            // and the last known mouse position
                            selected.setM_x(width - Math.abs(selected.getM_x() - mouse_x)); 
                            selected.setM_y(height - Math.abs(selected.getM_y() - mouse_y));
                            selected.setM_width(width + Math.abs(selected.getM_width() - mouse_x));
                            selected.setM_height(height + Math.abs(selected.getM_height() - mouse_y));
                           
                            
                            // update drawing buffer, blah blah
                                m_Settings.m_DrawBuffer.add(selected);
                                System.out.print(selected.getM_width());
                            
                            // clear the selection buffer
                            if (!m_Settings.m_SelectedBuffer.isEmpty()) {
                                m_Settings.m_SelectedBuffer.clear();
                                break;
                            }
                        }
                        break;
        }

        repaint();
    }

    public void mouseDragged(MouseEvent e)
    {
        // update the mouse coordinates
        width = e.getX();
        height = e.getY();
        
        // dont draw a brush if its outside the panel
        if (height > 0 && width > 0)
        {
            // if the selected tool is a brush
            if (m_Settings.getTool() == TOOLS.BRUSH)
            {
                // set the color of the brush and draw it based on the size
                Color c = m_Settings.getColor();
                addShape(new TBrush(c, width, height, m_Settings.getSize(), m_Settings.getSize()));
            }
        }
        else
            ;

        repaint();
    }

    // Utility function to check to see if a shape has been selected
    public void selectShape()
    {        
        // loop through each shape in the drawing buffer
        for (int i = 0; i < m_Settings.m_DrawBuffer.size(); i++) {
            TShape selected = m_Settings.m_DrawBuffer.get(i);
            
            // check the shapes x and y coordinates to see if the clicked area
            // is within the boundries of a shape.
            // If it is within the boundries, add it to the selected buffer,
            // remove it from the drawing buffer, and break out of the loop
             if (mouse_x > selected.getM_x() && mouse_y > selected.getM_y()
                    && mouse_x < selected.getM_width() && mouse_y < selected.getM_height())
            {
                m_Settings.m_SelectedBuffer.add(selected);
                m_Settings.m_DrawBuffer.remove(i);
                break;
            }
        }
    }
    //  utility function to clear the drawing buffer
    public void clearshapeList()
    {
        m_Settings.m_DrawBuffer.clear();
        repaint();
    }
    
    // sets the size of the paint brush according to what is selected
    public void setBrushSize(int size)
    {
        m_Settings.setSize(size);
    }

    /**
     * Paints the Objects
     * @param g
     */
    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D)g;
        
        // this call makes the lines appear straight
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
        RenderingHints.VALUE_ANTIALIAS_ON);

        switch(m_Settings.getTool()) {
            case LINE: g2d.draw(new Line2D.Double(mouse_x,mouse_y,width,height)); break;
            case CIRCLE: g2d.draw(new Ellipse2D.Double(mouse_x, mouse_y, width-mouse_x, height-mouse_y)); break;
            case BRUSH: g2d.fill(new Ellipse2D.Double(mouse_x, mouse_y, m_Settings.getSize(), m_Settings.getSize())); break;
            case RECTANGLE: g2d.draw(new Rectangle2D.Double(mouse_x, mouse_y, width - mouse_x, height-mouse_y)); break;
            case SELECTOR: // do nothing             
        }
        
        /**
         * This draws the objects currently in the DrawBuffer
         */
        
        for (int i = 0; i < m_Settings.m_DrawBuffer.size(); i++) {
            m_Settings.m_DrawBuffer.get(i).draw(g2d);
        }
    }

    // Checks button status, and sets the correct tool
    public void setButtonStatus(String isActive)
    {
        // checks the status of the buttons and then updates
        // this to correct object
        if (isActive.equals("line"))
            m_Settings.setTool(TPaintSettings.TOOLS.LINE);
        else if (isActive.equals("rect"))
            m_Settings.setTool(TPaintSettings.TOOLS.RECTANGLE);
        else if (isActive.equals("circle"))
            m_Settings.setTool(TPaintSettings.TOOLS.CIRCLE);
        else if (isActive.equals("triangle"))
            m_Settings.setTool(TPaintSettings.TOOLS.TRIANGLE);
        else if (isActive.equals("brush"))
            m_Settings.setTool(TPaintSettings.TOOLS.BRUSH);
        else if (isActive.equals("select"))
            m_Settings.setTool(TPaintSettings.TOOLS.SELECTOR);
    }

    // Checks the status of the clicked color panels and sets
    // the appropriate color
    public void setColor(String color)
    {
        // set the color of the object being drawn
        if (color.equals("red"))
            m_Settings.setColor(Color.RED);
        else if (color.equals("blue"))
            m_Settings.setColor(Color.BLUE);
        else if (color.equals("green"))
            m_Settings.setColor(Color.GREEN);
        else if (color.equals("black"))
            m_Settings.setColor(Color.BLACK);
        else
            ;
    }

    // sets fill appropriately according to the button
    public void setFill(String fill)
    {
        // do you want this to be a filled or non filled object
        this.fill = false;
        this.nonfill = false;

        if (fill.equals("fill"))
            m_Settings.setFilled(true);
        else if (fill.equals("nofill"))
            m_Settings.setFilled(false);
        else
            ;
    }
    /**
     * Unused mouseEvents
     * @param e
     */
    public void mouseClicked(MouseEvent e) {}
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
    public void mouseMoved(MouseEvent e) {
        if (m_Settings.m_fileloaded) {
            repaint();
            m_Settings.m_fileloaded = false;
        } 
    }
}
